package com.demo.sso.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping("/redis")
public class RedisController {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 生成递增的业务编码
     * 即使Redis宕机重启，也能继续叠加递增
     * 使用Redis的INCR命令（原子递增），配合Redis的持久化机制
     * @param prefix 编码前缀
     * @param pattern 日期格式模式，如 "yyyyMMdd"
     * @param paddingLength 数字部分的补零长度
     * @return 生成的业务编码
     */
    @PostMapping("/generateBusinessCode")
    public Map<String, Object> generateBusinessCode(
            @RequestParam String prefix,
            @RequestParam(required = false) String pattern,
            @RequestParam(required = false) Integer paddingLength) {
        
        // 默认值处理
        if (pattern == null) {
            pattern = "yyyyMMdd";
        }
        if (paddingLength == null) {
            paddingLength = 6;
        }
        
        // 生成日期部分
        String datePart = LocalDateTime.now().format(DateTimeFormatter.ofPattern(pattern));
        
        // 生成Redis键名，包含前缀和日期
        String redisKey = "business_code:" + prefix + ":" + datePart;
        
        // 使用Redis的INCR命令生成递增的序列号
        // Redis的INCR命令是原子性的，适合生成唯一序列号
        // 并且在Redis配置了持久化的情况下，即使Redis重启，数据也能恢复
        Long sequence = stringRedisTemplate.opsForValue().increment(redisKey);
        
        // 格式化序列号，不足paddingLength位的前面补零
        String sequenceStr = String.format("%0" + paddingLength + "d", sequence);
        
        // 组合前缀、日期和序列号生成最终的业务编码
        String businessCode = prefix + datePart + sequenceStr;
        
        // 构建返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("code", 200);
        result.put("message", "业务编码生成成功");
        result.put("businessCode", businessCode);
        result.put("timestamp", System.currentTimeMillis());
        
        return result;
    }
}